package org.yecq.tradedata.craw;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.util.LinkedList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.yecq.humblecrawler.FetchFailedException;
import org.yecq.humblecrawler.HumbleCrawler;
import org.yecq.tradedata.bean.FuturesDayKLineBean;

/**
 * 期货数据抓取 方法其实还是很简单，参考了http://blog.csdn.net/teddyu_leo/article/details/38308339
 *
 * @author yecq
 */
@Component
public class FuturesCrawler {

    @Autowired
    private HumbleCrawler craw;

    @Autowired
    private ExceptionDate excep_date;

    // 获取期货所有的日线历史数据，这个可以是一次性获取的
    public List<FuturesDayKLineBean> getHistoryDayKLines(String code) {
        List<FuturesDayKLineBean> ret = new LinkedList();
        if (code == null || code.trim().equals("")) {
            throw new IllegalArgumentException("错误的期货代号");
        }

        code = code.trim();
        String body = getHistoryRawString(code);
        List<List<String>> all = new Gson().fromJson(body, new TypeToken<List<List<String>>>() {
        }.getType());
        for (List<String> item : all) {
            if (item.isEmpty()) {
                throw new IllegalStateException("有合约为空");
            }
            try {
                FuturesDayKLineBean bean = new FuturesDayKLineBean();
                bean.setCode(code);
                bean.setDate(item.get(0));
                bean.setOpen(Double.parseDouble(item.get(1)));
                bean.setHigh(Double.parseDouble(item.get(2)));
                bean.setLow(Double.parseDouble(item.get(3)));
                bean.setClose(Double.parseDouble(item.get(4)));
                bean.setVol(Integer.parseInt(item.get(5)));
                ret.add(bean);
            } catch (NumberFormatException ex) {
                throw new FetchFailedException("期货数据格式有误 " + ex.getMessage());
            }
        }
        return ret;
    }

    private String getHistoryRawString(String code) {
        this.craw.markIgnoreContentType();
        return this.craw.getBody(Address.FUTURES_URL + code.trim());
    }

    // 获取期货当天的数据
    public FuturesDayKLineBean getTodayDayKLine(String code) {
        if (code == null || code.trim().equals("")) {
            throw new IllegalArgumentException("错误的期货代号");
        }
        code = code.trim();
        String body = getTodayRawString(code);
        String[] tmp = body.substring(body.indexOf("=\"") + 2, body.lastIndexOf("\"")).split(",");

        FuturesDayKLineBean bean = new FuturesDayKLineBean();
        if (tmp.length == 0 || tmp.length == 1) {
            throw new IllegalStateException("没有该合约" + code + "的当天数据");
        }
        try {
            bean.setCode(code);
            bean.setDate(tmp[17]);
            bean.setOpen(Double.parseDouble(tmp[2]));
            bean.setHigh(Double.parseDouble(tmp[3]));
            bean.setLow(Double.parseDouble(tmp[4]));
            bean.setClose(Double.parseDouble(tmp[8]));
            bean.setVol(Integer.parseInt(tmp[14]));
        } catch (NumberFormatException ex) {
            throw new FetchFailedException("期货数据格式有误 " + ex.getMessage());
        }

        if (this.excep_date.isExceptionDate(bean.getDate())) {
            throw new IllegalStateException("该日为非交易日");
        }
        return bean;
    }

    private String getTodayRawString(String code) {
        this.craw.markIgnoreContentType();
        return this.craw.getBody(Address.FUTURES_TODAY + code.trim());
    }
}
